package isquirrel.servlets;

import isquirrel.FacebookAPI;
import isquirrel.UserManager;
import isquirrel.beans.Friend;
import isquirrel.beans.Url;
import isquirrel.beans.User;
import isquirrel.recommender.StaticRecommender;
import isquirrel.servlets.handler.HttpDBServlet;
import isquirrel.util.HibernateUtil;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import org.json.JSONException;


/**
 * Servlet implementation class Profiler
 */
public class Profiler extends HttpDBServlet {
	private static final long serialVersionUID = 1L;
	
	/* usages of the Profiler servlet */
	private static final int RENDER_SUBPAGE = 0;
	private static final int UPDATE_USER_NETWORK = 1;
	private static final int LOAD_PIC_SQUARE = 2;
	
    /**
     * @see HttpServlet#HttpServlet()
     */
    public Profiler() {
        super();
    }

	private void renderLikes(User u) throws Exception{
    	
    	List<Url> urls = StaticRecommender.getLikes(u, -7);
    	
    	Vector<Url> urls_v = new Vector<Url>();
    	urls_v.addAll(urls);
    	Collections.shuffle(urls_v);
		urls_v.setSize(7);
		
		/* if the user's friends have changed we invalidate the session for the changes to appear on the next
		 * page refresh
		 */
		
		request.getSession().setAttribute("urlsnum",u.getLikedUrls().size());
		request.getSession().setAttribute("urls",urls_v);
    }
    
    private void renderFriends(User u) throws Exception{
    	FacebookAPI api = new FacebookAPI();

    	/* get the user's friends which are facebook users together with their facebook pics*/
		Vector<Friend> fbfriends = api.getUser_FBFriends(u);
		Set<User> allfriends = u.getFriends();
		
		/* we now need to figure out which user's are "pure" isquirrel friends i.e not on facebook so we can assign them
		 * a 'no image' profile pic
		 */
		Vector<Friend> nofbfriends = new Vector<Friend>();
		
		for (User friend : allfriends){
			if (friend.getFbID() == 0){
				String pic = "/" + request.getRequestURI().split("/")[1] + "/images/";
				if (friend.getSex().equals("Male")){
					pic += "nopicmale.png";
				}
				else {
					pic += "nopicfemale.png";
				}
				nofbfriends.add(new Friend(friend.getFirstName() + " " + friend.getLastName(),
										   0L , 
										   friend.getUserID(), 
										   pic,
										   friend.getLikedUrls().size(),
										   u.compare(friend)
											));						    
			}		
		}
		Vector<Friend> friends = new Vector<Friend>();
		
		/* we add the two collections */
		if (fbfriends != null && fbfriends.size() > 0){
			friends.addAll(fbfriends);			
		}
		if (nofbfriends != null && nofbfriends.size() > 0){
			friends.addAll(nofbfriends);
		}
		
		int new_friends = friends.size();
		
		/* shuffling allows for a different set of friends to be displayed each time a page is loaded */
		Collections.shuffle(friends);
		
		request.getSession().setAttribute("friendsnum",new_friends);
		request.getSession().setAttribute("friends",friends);

    }
    
	@Override
	protected void handleGet() throws ServletException, IOException,
			JSONException {
		
		/* GET is handled for all redirects from Fudel 
		 * from the registration success page and from 'forcing' to view a certain tab 
		 */
		String nextp = request.getParameter("nextp");	
		String force = null;
		if (request.getParameter("force") != null){
			force = (String) request.getParameter("force");
		}
		
    	User u = (UserManager.getUser((String) request
				.getSession()
				.getAttribute("user")));
    	if (u == null){
			response.sendRedirect("/" + request.getRequestURI().split("/")[1] + "/views/pagetabs/expired.jsp");
    	}
		else{
			try {
				renderFriends(u);
				renderLikes(u);
			}
			catch(Exception e){
				response.sendRedirect("/" + request.getRequestURI().split("/")[1] + "/views/pagetabs/expired.jsp");
				return;
			}
			if (force != null){
				request.getSession().setAttribute("force", force);
			}
			response.sendRedirect("/" + request.getRequestURI().split("/")[1] + "/" + nextp);
		}	
	}

	@Override
	protected void handlePost() throws ServletException, IOException,
			JSONException {
		Integer type = Integer.valueOf(request.getParameter("type"));
		
		switch (type){
		
			case RENDER_SUBPAGE: {
					
				/* we need to render a subpage */
				String view = "/views/pagetabs/" + request.getParameter("p").toLowerCase() + ".jsp";
//				System.out.println(view);
				
				User u = (UserManager.getUser((String) request
						.getSession()
						.getAttribute("user")));
				
				if (u == null){
					response.sendRedirect("/" + request.getRequestURI().split("/")[1] + "/views/pagetabs/expired.jsp");
					return;
				}
				else{
					try{
						renderFriends(u);
						renderLikes(u);
					}
					catch(Exception e){
						e.printStackTrace();
						response.sendRedirect("/" + request.getRequestURI().split("/")[1] + "/views/pagetabs/expired.jsp");
						return;
					}
					response.sendRedirect("/" + request.getRequestURI().split("/")[1] + view);
				}
				break;
				/* end RENDER_SUBPAGE */
			}
	
			case UPDATE_USER_NETWORK: {
			
				/* we need the intersection of the user's FB friends and the whole iSquirrel community */
				
				String fb = request.getParameter("friends").replace("\"","");				
				
				String[] fb_friends = fb.split("\\+");
				
				Set<User> matched = new HashSet<User>();
						
				List<User> isq_users = UserManager.getUsers();
				Long[] fb_friends_l = new Long[fb_friends.length];
				
				for (int i = 0; i < fb_friends_l.length; ++i){
					fb_friends_l[i] = Long.parseLong(fb_friends[i]);
				}
				
				Arrays.sort(fb_friends_l);
				Iterator<User> isqfi = isq_users.iterator();
				while(isqfi.hasNext()){
					
					User u = isqfi.next();
					int index = Arrays.binarySearch(fb_friends_l,u.getFbID());
					
					if (index >=0 && index < fb_friends_l.length){ matched.add(u);}
						
				}
				
				User user = getLoggedInUser();
				if (!matched.isEmpty()){
					
					Set<User> users_friends = user.getFriends();
					
					matched.removeAll(users_friends);
					if (!matched.isEmpty()){
						users_friends.addAll(matched);
					}
					user.setFriends(users_friends);
						
				}
				if (user.getIsProfileInit() == 0){
					user.setIsProfileInit(1);
				}
				HibernateUtil.getSession().saveOrUpdate(user);
				response.getWriter().print("OK");
				break;
				/* end UPDATE_USER_NETWORK */
			}
		}
		
		
		
	}

}
